/* SPDX-License-Identifier: GPL-2.0 */

#ifndef	DIM_RB_TREE_H
#define	DIM_RB_TREE_H

typedef void *dim_rb_handle;

/**
 * data comparison callback function, return negative if data1 less then
 * data2, positive if data1 larger then data2, otherwise return 0
 */
typedef int (*dim_rb_compare)(void *data1, void *data2);

/**
 * create dim rb root handle and set the comparison function,
 * return void handle pointer, caller not care the struction of the handle
 */
dim_rb_handle dim_rb_create(dim_rb_compare comp_func);

/**
 * dim_rb_find_data - find the data pointer which is linked in the rb tree.
 * @root: rb tree to find
 * @data: input data, which should be searched in the rb tree,
 *        dim_rb_find_data not care the struction of the data,
 *        it will call comparison function to search, caller
 *        should structure a temporary data pointer as the input
 *        parameter if the data is not a simple string, number.
 *
 * Return: NULL if not found.
 */
void *dim_rb_find_data(dim_rb_handle root, void *data);

/**
 * dim_rb_insert_data - insert a new data pointer into dim rb tree.
 * @root: rb tree to find
 * @new_data: input data, new data pointer
 * @find_data: output data, if we found a data in dim rb tree
 *             which the key value is same, we will output this
 *             data pointer and return error code -EEXIST,
 *             caller should deside are there any problems.
 *             (normally, it is impossible that there are two
 *             rb node which have same key value.)
 * Return: -EINVAL, parameter error
 *         -EFAULT, dim rb tree has some unknown problems, it can not work,
 *                  maybe the tree should be rebuild.
 *         -EEXIST, data exit
 *         -ENOMEM, not enough memory
 *         0, no error, and insert successfully
 */
int dim_rb_insert_data(dim_rb_handle root, void *new_data, void **find_data);

/**
 * dim_rb_destroy - destroy dim rb handle
 * @root: rb tree to destroy
 */
void dim_rb_destroy(dim_rb_handle root);

/**
 * dim_rb_first_data - get first data pointer in rb tree
 * @root: rb tree to find
 *
 * Return: pointer of data or NULL
 */
void *dim_rb_first_data(dim_rb_handle root);

/**
 * dim_rb_next_data - get next data pointer in rb tree, it should be called
		      after dim_rb_first_data, dim_rb_next_data can be called
		      again and again, and it will return data pointer one by
		      one as ascending order. return NULL if no more one.
 * @root: rb tree to find
 *
 * Return: pointer of data or NULL
 */
void *dim_rb_next_data(dim_rb_handle root);

/*
 * dim_rb_remove_first_data - remove the first node from dim rb tree, and free
 * the rb node in this function, the data pointer should be freed by caller.
 * it can be called in a loop to remove and free all of the list.
 * @root: rb tree to find
 *
 * Return: pointer of data or NULL
 */
void *dim_rb_remove_first_data(dim_rb_handle root);

#endif /* DIM_RB_TREE_H */
